wayland: apply empty input shape on parent commit
authorOlivier Fourdan <ofourdan@redhat.com>
Wed, 16 Nov 2016 14:05:43 +0000 (15:05 +0100)
committerOlivier Fourdan <ofourdan@redhat.com>
Thu, 15 Dec 2016 12:27:39 +0000 (13:27 +0100)
For subsurfaces, the new state which includes the input shape is not
applied by the compositor if the subsurface is in effective synchronous
mode.

So we need to apply the input shape once parent surface is in effective
desynchronized mode, which is when it's committed, otherwise the input
shape may never be applied if the widget is not using being_paint() /
end_paint() to draw on its subsurface, like clutter does.

We do that only for empty input shape as those won't need update when
the subsurface is resized, for all other non-empty input shape, the
client still has to use begin_paint()/end_paint() for the input shape to
be applied.

https://bugzilla.gnome.org/show_bug.cgi?id=774534

gdk/wayland/gdkwindow-wayland.c

index 09387b75105a74fb55cab244f4c5abde1a65e7d4..eb28ec54be69d9bd48cda22a3eb4275c5243ff59 100644 (file)
@@ -1193,6 +1193,31 @@ gdk_wayland_window_sync_input_region (GdkWindow *window)
   impl->input_region_dirty = FALSE;
 }
 
+static void
+gdk_wayland_set_input_region_if_empty (GdkWindow *window)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkWaylandDisplay *display;
+  struct wl_region *empty;
+
+  if (!impl->input_region_dirty)
+    return;
+
+  if (impl->input_region == NULL)
+    return;
+
+  if (!cairo_region_is_empty (impl->input_region))
+    return;
+
+  display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+  empty = wl_compositor_create_region (display->compositor);
+
+  wl_surface_set_input_region (impl->display_server.wl_surface, empty);
+  wl_region_destroy (empty);
+
+  impl->input_region_dirty = FALSE;
+}
+
 static void
 surface_enter (void              *data,
                struct wl_surface *wl_surface,
@@ -1242,6 +1267,9 @@ on_parent_surface_committed (GdkWindowImplWayland *parent_impl,
   impl->parent_surface_committed_handler = 0;
 
   wl_subsurface_set_desync (impl->display_server.wl_subsurface);
+
+  /* Special case if the input region is empty, it won't change on resize */
+  gdk_wayland_set_input_region_if_empty (window);
 }
 
 static void